﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Soundelle.Oscillator
{
     public class FilterAverage:BaseDevice
    {
        public FilterAverage()
        {
        }

        private ParameterType[] _AvailableParameters = { 
            ParameterType.Parameter_DC_Offset,
            ParameterType.Parameter_Amplitude,
            ParameterType.Parameter_Averages
        };
        override public ParameterType[] AvailableParameters
        {
            get
            { return _AvailableParameters; }
        }

        private DeviceFunctionType[] _AvailableFunctions = new DeviceFunctionType[] {
             DeviceFunctionType.Function_FilterAverage,
             DeviceFunctionType.Function_FilterAverageRMS,
             DeviceFunctionType.Function_FilterAverageMS,
             DeviceFunctionType.Function_Thru
        };
        override public DeviceFunctionType[] AvailableFunctions
        {
            get
            { return _AvailableFunctions; }
        }

        override public void Reset()
        {
            prevSig = 0.0;
            averageCount = 0;
            base.Reset();
        }

        double prevSig = 0.0;
        long averageCount = 0;

        override public double SignalOut()
        {
            if (!Enabled)
                return 0.0;

            double signalOut = 0.0;
            double signalIn = 0.0;

            double DcOffset =Parameter_DC_Offset;
            double amplitude = Parameter_Amplitude;
            double frequency = 0.0;
            double phase = Parameter_Phase;

            double duty = Parameter_Duty;

            long averages = Parameter_Averages;

            DoModulationByChildDevices(ref signalOut, ref signalIn, ref amplitude, ref frequency, ref phase, ref duty);

            //----

            double sig = 0.0;

            if (averages < 1)
                averages = 1;

            switch (Function)
            {
                case DeviceFunctionType.Function_FilterAverageRMS:
                    sig = (prevSig * (double)averageCount + Math.Pow (amplitude * signalIn,2.0)) / ((double)averageCount + 1.0) ;

                    if ( (averageCount + 1) < averages )
                        ++averageCount;

                    prevSig = sig;
                    sig = Math.Sqrt(sig);
                    break;

                case DeviceFunctionType.Function_FilterAverageMS:
                    sig = (prevSig * (double)averageCount + Math.Pow(amplitude * signalIn, 2.0)) / ((double)averageCount + 1.0);

                    if ((averageCount + 1) < averages)
                        ++averageCount;

                    prevSig = sig;
                    break;

                case DeviceFunctionType.Function_FilterAverage:
                    sig = (prevSig * (double)averageCount + amplitude * signalIn) / ((double)averageCount + 1.0);

                    if ((averageCount + 1) < averages)
                        ++averageCount;

                    prevSig = sig;
                    break;

                case DeviceFunctionType.Function_Thru:
                    sig =　amplitude * signalIn;
                    break;

                default:
                    break;
            }

            ++TimePosition;
            double SignalOut = sig +  signalOut + DcOffset;
            SetPreviousSignalOut(SignalOut);
            return SignalOut;
        }  
    }
}
